package com.liu.voluntary.handler;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/webSocket")
@Slf4j
public class WebSocket {
    private Session session;

    // 使用ConcurrentHashMap来存储会话，使用用户手机号作为key
    private static final Map<String, WebSocket> CLIENTS = new ConcurrentHashMap<>();
    // 存储Session ID到用户手机号的映射
    private static final Map<String, String> SESSION_USER_MAP = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session) {
        String sessionId = session.getId();
        this.session = session;
        log.info("【websocket消息】新的连接已建立，sessionId={}", sessionId);
    }

    // 将用户与WebSocket会话关联
    public void associateUser(String userMobile) {
        if (this.session == null) {
            log.error("无法关联用户 {}: WebSocket会话为空", userMobile);
            return;
        }

        String sessionId = this.session.getId();
        
        // 如果该用户已经有关联的会话，先关闭旧会话
        WebSocket oldSocket = CLIENTS.get(userMobile);
        if (oldSocket != null && oldSocket.session != null) {
            try {
                String oldSessionId = oldSocket.session.getId();
                SESSION_USER_MAP.remove(oldSessionId);
                oldSocket.session.close();
                log.info("关闭用户{}的旧连接: {}", userMobile, oldSessionId);
            } catch (IOException e) {
                log.error("关闭旧连接时出错", e);
            }
        }

        // 建立新的关联
        CLIENTS.put(userMobile, this);
        SESSION_USER_MAP.put(sessionId, userMobile);
        log.info("用户{}已关联到会话{}", userMobile, sessionId);
    }

    @OnClose
    public void onClose(Session session) {
        String sessionId = session.getId();
        String userMobile = SESSION_USER_MAP.remove(sessionId);
        if (userMobile != null) {
            CLIENTS.remove(userMobile);
            log.info("【websocket消息】用户{}的连接已断开，sessionId={}", userMobile, sessionId);
        }
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            // 解析JSON消息
            JSONObject jsonMessage = JSON.parseObject(message);
            String type = jsonMessage.getString("type");
            
            if ("associate".equals(type)) {
                String mobile = jsonMessage.getString("mobile");
                if (mobile != null && !mobile.isEmpty()) {
                    // 关联用户和会话
                    CLIENTS.put(mobile, this);
                    SESSION_USER_MAP.put(session.getId(), mobile);
                    log.info("用户{}与WebSocket会话关联成功", mobile);
                }
            }
        } catch (Exception e) {
            log.error("处理WebSocket消息时发生错误", e);
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        String sessionId = session.getId();
        String userMobile = SESSION_USER_MAP.get(sessionId);
        log.error("WebSocket发生错误，用户={}, 错误信息: {}", userMobile, error.getMessage());
        if (userMobile != null) {
            CLIENTS.remove(userMobile);
            SESSION_USER_MAP.remove(sessionId);
        }
    }

    // 发送消息给指定用户，返回是否发送成功
    public boolean sendMessageToUser(String userMobile, String message) {
        WebSocket webSocket = CLIENTS.get(userMobile);
        if (webSocket != null && webSocket.session != null && webSocket.session.isOpen()) {
            try {
                webSocket.session.getBasicRemote().sendText(message);
                log.info("消息已成功发送给用户: {}", userMobile);
                return true;
            } catch (IOException e) {
                log.error("发送消息给用户{}失败: {}", userMobile, e.getMessage());
                CLIENTS.remove(userMobile);
                SESSION_USER_MAP.remove(webSocket.session.getId());
                return false;
            }
        } else {
            log.warn("用户{}不在线或连接已关闭", userMobile);
            if (webSocket != null) {
                CLIENTS.remove(userMobile);
                if (webSocket.session != null) {
                    SESSION_USER_MAP.remove(webSocket.session.getId());
                }
            }
            return false;
        }
    }

    // 广播消息给所有用户
    public void sendMessage(String message) {
        log.info("准备广播消息，当前活动连接数: {}", CLIENTS.size());
        
        CLIENTS.forEach((userMobile, webSocket) -> {
            try {
                if (webSocket.session != null && webSocket.session.isOpen()) {
                    webSocket.session.getBasicRemote().sendText(message);
                    log.info("消息已发送到用户: {}", userMobile);
                } else {
                    log.warn("用户{}的会话已关闭，移除连接", userMobile);
                    CLIENTS.remove(userMobile);
                    if (webSocket.session != null) {
                        SESSION_USER_MAP.remove(webSocket.session.getId());
                    }
                }
            } catch (IOException e) {
                log.error("发送消息到用户{}失败: {}", userMobile, e.getMessage());
                CLIENTS.remove(userMobile);
                if (webSocket.session != null) {
                    SESSION_USER_MAP.remove(webSocket.session.getId());
                }
            }
        });
    }
}
